#include "net_client.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h> // 提供 free、malloc 函数声明
#include <stdio.h>  // 提供 snprintf 函数声明

// 全局连接状态
int g_sockfd = -1;
static NetConfig g_config;
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; // 线程安全锁

// 连接服务器（内部函数）
static bool connect_server(void)
{
    // 已连接则直接返回
    if(g_sockfd != -1) {
        printf("[NET] 已建立连接，sockfd=%d\n", g_sockfd);
        return true;
    }

    printf("[NET] 开始连接服务器 %s:%d\n", g_config.ip, g_config.port);

    // 创建socket
    g_sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(g_sockfd < 0) {
        printf("[NET] 创建socket失败！错误码: %d\n", errno);
        return false;
    }
    printf("[NET] socket创建成功，sockfd=%d\n", g_sockfd);

    // 设置服务器地址
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port   = htons(g_config.port);
    if(inet_pton(AF_INET, g_config.ip, &server_addr.sin_addr) <= 0) {
        printf("[NET] IP地址解析失败！IP=%s\n", g_config.ip);
        close(g_sockfd);
        g_sockfd = -1;
        return false;
    }

    // 连接服务器
    if(connect(g_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        printf("[NET] 连接服务器失败！错误码: %d\n", errno);
        close(g_sockfd);
        g_sockfd = -1;
        return false;
    }

    printf("[NET] 成功连接到服务器 %s:%d\n", g_config.ip, g_config.port);
    return true;
}

// 子线程：处理发送请求并等待响应
static void * net_worker(void * arg)
{
    WorkerArg * arg_data = (WorkerArg *)arg;
    printf("[NET] 开始处理消息，类型=%d，数据=%s\n", arg_data->type, arg_data->data);
    char send_buf[1024] = {0}; // 发送缓冲区（1KB，与原逻辑一致）
    char recv_buf[1024] = {0}; // 接收缓冲区（1KB，与原逻辑一致）
    // 1. 堆分配 NetResponse（指针类型）
    NetResponse * resp = (NetResponse *)malloc(sizeof(NetResponse));
    if(!resp) {
        printf("[NET] 错误：NetResponse 内存分配失败\n");
        arg_data->callback(NULL); // 传递空指针，避免回调异常
        free(arg_data);
        return NULL;
    }

    // 2. 初始化 resp 成员（用 -> 访问指针）
    resp->type      = arg_data->type;
    resp->user_data = arg_data->user_data; // 此时 user_data 是 SCREEN1_ID（int 类型）
    resp->code      = -1;
    resp->data      = NULL;

    pthread_mutex_lock(&g_mutex);
    if(!connect_server()) {
        resp->code = -2;
        printf("[NET] 连接服务器失败，错误码=%d\n", resp->code);
        pthread_mutex_unlock(&g_mutex);
        // 关键修正1：传递 resp（指针），而非 &resp（指针的地址）
        arg_data->callback(resp);
        free(arg_data);
        return NULL;
    }
    snprintf(send_buf, sizeof(send_buf), "%d:%s",
             arg_data->type,  // 消息类型（如 MSG_TYPE_LOGIN=1）
             arg_data->data); // 实际数据（如 "账号:密码"）
    printf("[NET] 待发送数据：%s（长度：%zu）\n", send_buf, strlen(send_buf));


    // 发送数据逻辑...
    ssize_t send_len = send(g_sockfd, send_buf, strlen(send_buf), 0);
    if(send_len == -1) {
        // 真正的发送错误（如网络异常）
        printf("[NET] send 失败！errno=%d，原因：%s\n", errno, strerror(errno));
        resp->code = -3; // 发送失败
        close(g_sockfd);
        g_sockfd = -1;
    } else if(send_len == 0) {
        // 对方关闭连接（正常关闭，非错误，但需要重新连接）
        printf("[NET] send 返回 0：服务器已关闭连接，需要重新连接\n");
        resp->code = -6; // 新增错误码：连接已关闭
        close(g_sockfd);
        g_sockfd = -1; // 标记连接无效，下次发送会重新连接
    } else {
        // 发送成功
        printf("[NET] 数据发送成功，长度=%zd，内容=%s\n", send_len, send_buf);
    }
    // 接收数据逻辑...
    ssize_t recv_len = recv(g_sockfd, recv_buf, sizeof(recv_buf) - 1, 0);
    if(recv_len <= 0) {
        resp->code = -4;
        printf("[NET] 接收响应失败，错误码=%d\n", resp->code);
        printf("[NET] 数据发送失败，错误码=%d，发送内容=%s\n", resp->code, send_buf);
        pthread_mutex_unlock(&g_mutex);
        // 关键修正3：传递 resp 指针
        arg_data->callback(resp);
        free(arg_data);
        return NULL;
    }
    recv_buf[recv_len] = '\0'; // 确保字符串结束
    resp->code         = 0;
    resp->data = strdup(recv_buf);  
    if(!resp->data) {
        resp->code = -5;
    }
    pthread_mutex_unlock(&g_mutex);

    // 关键修正4：传递 resp 指针
    arg_data->callback(resp);
    free(arg_data);
    printf("[NET] 消息处理完成\n");
    return NULL;
}
// 初始化网络模块
void net_client_init(NetConfig * config)
{
    if(config) {
        g_config = *config;
        printf("[NET] 网络模块初始化，服务器IP=%s，端口=%d，超时=%dms\n", g_config.ip, g_config.port,
               g_config.timeout_ms);
    } else {
        printf("[NET] 网络模块初始化，使用默认配置\n");
    }
    pthread_mutex_init(&g_mutex, NULL);
}

// 发送消息（外部接口）
bool net_client_send(MsgType type, const char * data, NetCallback callback, void * user_data)
{
    if(!data || !callback) {
        printf("[NET] 发送失败：数据或回调函数为空\n");
        return false;
    }

    // 分配子线程参数
    WorkerArg * arg = (WorkerArg *)malloc(sizeof(WorkerArg));
    if(!arg) {
        printf("[NET] 发送失败：内存分配失败\n");
        return false;
    }

    arg->type = type;
    strncpy(arg->data, data, sizeof(arg->data) - 1);
    arg->callback  = callback;
    arg->user_data = user_data;

    // 新增：设置线程栈大小（16KB，解决栈溢出）
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    size_t stack_size = 16 * 1024; // 16KB（默认栈可能只有 8KB）
    if(pthread_attr_setstacksize(&attr, stack_size) != 0) {
        printf("[NET] 警告：线程栈大小设置失败，使用默认值\n");
    }
    pthread_t tid;
    if(pthread_create(&tid, &attr, net_worker, arg) != 0) {
        free(arg);
        pthread_attr_destroy(&attr); // 销毁属性
        printf("[NET] 发送失败：创建线程失败\n");
        return false;
    }

    pthread_attr_destroy(&attr); // 销毁属性
    pthread_detach(tid);
    printf("[NET] 成功创建网络线程（类型=%d）\n", type);
    return true;
}

// 在 net_client.c 中添加
void net_send_private_msg(int to_user_id, const char* msg) {
    if (!msg || to_user_id == 0) return;
    
    // 实现发送逻辑（示例）
    char send_buf[512];
    snprintf(send_buf, sizeof(send_buf), "20:%d:%s", to_user_id, msg);
    send(g_sockfd, send_buf, strlen(send_buf), 0);
}
// 断开连接
void net_client_disconnect(void)
{
    pthread_mutex_lock(&g_mutex);
    if(g_sockfd != -1) {
        printf("[NET] 断开与服务器的连接，sockfd=%d\n", g_sockfd);
        close(g_sockfd);
        g_sockfd = -1;
    } else {
        printf("[NET] 未连接到服务器，无需断开\n");
    }
    pthread_mutex_unlock(&g_mutex);
}